package org.dna.metronomo.persistence.impl;

import java.sql.SQLException;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.dna.metronomo.persistence.IIssueDAO;
import org.dna.metronomo.persistence.PersistenceException;
import org.tigris.scarab.model.Issue;
import org.apache.log4j.Logger;
import org.dna.metronomo.persistence.impl.annotations.SessionField;
import org.dna.metronomo.persistence.impl.annotations.SessionMethod;
import org.tigris.scarab.mapper.ActivityMapper;
import org.tigris.scarab.mapper.IssueMapper;
import org.tigris.scarab.mapper.IssueTypeMapper;
import org.tigris.scarab.mapper.TransactionMapper;
import org.tigris.scarab.model.Activity;
import org.tigris.scarab.model.ActivityTypeEnum;
import org.tigris.scarab.model.IssueType;
import org.tigris.scarab.model.Module;
import org.tigris.scarab.model.Transaction;

/**
 *
 * @author andrea
 */
public class IBatisIssueDAO implements IIssueDAO {
    
    //NB known to be 3 from the metronomo-init.sql script
    static final int STATUS_ATTRIBUTE_ID = 3;
    
    @SessionField
    SqlSession m_session;

    private final static Logger LOG = Logger.getLogger(IBatisIssueDAO.class);

    @SessionMethod
    public List<Issue> allIssues() throws PersistenceException {
        IssueMapper mapper = m_session.getMapper(IssueMapper.class);
        return mapper.listAll();
    }

    @SessionMethod
    public List<IssueType> allTypes() throws PersistenceException {
        IssueTypeMapper mapper = m_session.getMapper(IssueTypeMapper.class);
        return mapper.allTypes();
    }

    @SessionMethod
    public void insert(final Issue issue, final Module module, final IssueType type) throws PersistenceException {
                //TODO verify the not null fields
                
                //insert a new transaction to store the event of an Issue creation
                Transaction issueCreationTransaction = new Transaction();
                TransactionMapper transactionMapper = m_session.getMapper(TransactionMapper.class);
                transactionMapper.insert(issueCreationTransaction);
                long transactionId = transactionMapper.findLastKey();
                issueCreationTransaction.setTransactionId(transactionId);
                
                //insert all competing activities
//                Activity createIssueActivity = new Activity();
//                createIssueActivity.setAttributeId(Integer.MIN_VALUE); //TODO
//                createIssueActivity.setActivityType(ActivityTypeEnum.ISSUE_CREATED);
//                ActivityMapper activityMapper = m_session.getMapper(ActivityMapper.class);
//                activityMapper.insert(createIssueActivity, issueCreationTransaction);
//                m_session.commit();

                IssueMapper mapper = m_session.getMapper(IssueMapper.class);
                //select max count for the same module and prefix
                int count = mapper.maxCount(issue.getPrefix(), module);
                if (issue.getCount() == null) {
                    issue.setCount(count + 1);
                }
                mapper.insert(issue, issueCreationTransaction, module, type);
                long lastInsertIssueID = mapper.lastInsertedKey();
//                m_session.commit();

                Activity createIssueActivity = new Activity();
                createIssueActivity.setAttributeId(STATUS_ATTRIBUTE_ID);
                createIssueActivity.setActivityType(ActivityTypeEnum.ISSUE_CREATED);
                createIssueActivity.setNewValue("New");
                ActivityMapper activityMapper = m_session.getMapper(ActivityMapper.class);
                activityMapper.insert(createIssueActivity, issueCreationTransaction, lastInsertIssueID);

                LOG.info("Executing IssueMapper.insert, inserted with " + issue);
    }
    
    @SessionMethod
    public Issue findByID(long key) throws PersistenceException {
        IssueMapper mapper = m_session.getMapper(IssueMapper.class);
        return mapper.selectByID(key);
    }
}
